﻿/// ##############################################################################
/// 
/// Original Author         : Nick Hoggard (nick@silvercode.co.nz)
/// 
/// ##############################################################################
/// License and Copywrite information
/// 
/// Copyright (c) 2010, Nick Hoggard (nick@silvercode.co.nz)
/// All rights reserved.
/// 
/// Redistribution and use in source and binary forms, with or without
/// modification, are permitted provided that the following conditions are met:
///     * Redistributions of source code must retain the above copyright
///       notice, this list of conditions and the following disclaimer.
///     * Redistributions in binary form must reproduce the above copyright
///       notice, this list of conditions and the following disclaimer in the
///       documentation and/or other materials provided with the distribution.
///     * Neither the name of the copywrite holder nor the names of its contributors 
///       may be used to endorse or promote products derived from this software 
///       without specific prior written permission.
/// 
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
/// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
/// DISCLAIMED. IN NO EVENT SHALL Nick Hoggard BE LIABLE FOR ANY
/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// ##############################################################################

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Controls;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using TimeSheetControl.ObjectModel;

namespace TimeSheetControl
{
	public partial class WorkItemTimeSheetControl 
		: UserControl, IWorkItemControl
	{
		public WorkItemTimeSheetControl()
		{
			InitializeComponent();
		}

		private object _workItemDataSource;

		private WorkItem CurrentWorkItem
		{
			get
			{
				return WorkItemDatasource as WorkItem;
			}
		}

		private TimeSheet TimeSheet { get; set;}

		#region IWorkItemControl Members

		public event EventHandler AfterUpdateDatasource;
		public event EventHandler BeforeUpdateDatasource;

		public void Clear()
		{
		}

		public void FlushToDatasource()
		{
			
		}

		public void InvalidateDatasource()
		{
			// Validate that the WorkItemFieldName property has been set
			if (string.IsNullOrEmpty(WorkItemFieldName))
			{
				throw new ArgumentNullException("The fieldname property for the WorkItemTimeSheetControl is not set");
			}

			// Reset the form to default values
			TimeSheet = null;
			dtDate.Value = DateTime.Today;
			nTimeSpent.Value = 1;
			txtComments.Text = string.Empty;

			// CurrentWorkItem can be null when unloading a work item form
			if (CurrentWorkItem == null)
			{
				return;
			}

			// Load the timesheet data from the work item if it is available.
			if (CurrentWorkItem.Fields[WorkItemFieldName].Value == null 
				|| string.IsNullOrEmpty(CurrentWorkItem.Fields[WorkItemFieldName].Value.ToString()))
			{
				TimeSheet = new TimeSheet();
			}
			else
			{
				TimeSheet = TimeSheet.Deserialize(CurrentWorkItem.Fields[WorkItemFieldName].Value.ToString());
			}

			dataGridView1.DataSource = TimeSheet;
		}

		public System.Collections.Specialized.StringDictionary Properties
		{
			get;
			set;
		}
		public bool ReadOnly
		{
			get;
			set;
		}
		public string WorkItemFieldName
		{
			get;
			set;
		}


		protected IServiceProvider _serviceProvider = null;
		public void SetSite(IServiceProvider serviceProvider)
		{
			_serviceProvider = serviceProvider;
		}

		public object WorkItemDatasource
		{
			get
			{
				return _workItemDataSource;
			}
			set
			{
				_workItemDataSource = value;
			}
		}

	  

		
		#endregion

		private void btnAddEntry_Click(object sender, EventArgs e)
		{
			TimeSheetEntry tse = new TimeSheetEntry();
			tse.CreatedBy = CurrentWorkItem.Store.TeamProjectCollection.AuthorizedIdentity.DisplayName;
			tse.CreatedDate = DateTime.Now;
			tse.Minutes = nTimeSpent.Value * 60;
			tse.TimeSheetDate = dtDate.Value;
			tse.Comments = txtComments.Text;
			TimeSheet.Add(tse);
			CurrentWorkItem.Fields[WorkItemFieldName].Value = TimeSheet.Serialize(TimeSheet);

			decimal completedWork = GetCompletedWork();

			completedWork = completedWork + (tse.Minutes / 60);
			SetCompletedWork(completedWork);


			// Reduce the 'Remaining Work'

			decimal remainingWork = GetRemainingWork();

			remainingWork = remainingWork - (tse.Minutes / 60);

			if (remainingWork < 0)
				remainingWork = 0;

			SetRemainingWork(remainingWork);
						
		}

		private void SetRemainingWork(decimal remainingWork)
		{
			CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value = remainingWork;
		}

		private void SetCompletedWork(decimal completedWork)
		{
			CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value = completedWork;
		}

		private decimal GetCompletedWork()
		{
			decimal completedWork = 0;
			// Add to the 'Completed Work' 
			if (CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"] != null
				&& CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value != null
				&& !string.IsNullOrEmpty(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value.ToString()))
			{

				decimal.TryParse(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value.ToString(), out completedWork);
			}
			return completedWork;
		}

		private decimal GetRemainingWork()
		{
			decimal remainingWork = 0;
			// Add to the 'Completed Work' 
			if (CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"] != null
				&& CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value != null
				&& !string.IsNullOrEmpty(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value.ToString()))
			{

				decimal.TryParse(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value.ToString(), out remainingWork);
			}
			return remainingWork;
		}

		private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
		{
			// Make sure it's the delele button (column 5), and
			// the row index is valid.
			if (e.ColumnIndex == 5 && e.RowIndex >= 0) 
			{
				decimal completedWork = GetCompletedWork();
				decimal remainingWork = GetRemainingWork();


				DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

				TimeSheetEntry tse = row.DataBoundItem as TimeSheetEntry;

				remainingWork += (tse.Minutes / 60);
				completedWork -= (tse.Minutes / 60);

				if (completedWork < 0)
					completedWork = 0;

				dataGridView1.DataSource = null;

				TimeSheet.Remove(tse);
				dataGridView1.DataSource = TimeSheet;
				
				CurrentWorkItem.Fields[WorkItemFieldName].Value = TimeSheet.Serialize(TimeSheet);

				SetCompletedWork(completedWork);
				SetRemainingWork(remainingWork);

				InvalidateDatasource();
			}
		}

		private void bindingSource1_CurrentChanged(object sender, EventArgs e)
		{

		}

	}
}
